home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DTP / DTP_TEX / H219.ZIP / DVIPSSRC.ZIP / dvips / prescan.c < prev    next >
C/C++ Source or Header  |  1993-04-20  |  10KB  |  294 lines

  1. /*
  2.  *   This is the main routine for the first (prescanning) pass.
  3.  */
  4. #include "dvips.h" /* The copyright notice in that file is included too! */
  5. /*
  6.  *   These are all the external routines it calls:
  7.  */
  8. extern void error() ;
  9. extern shalfword dvibyte() ;
  10. extern integer signedquad() ;
  11. extern int skipnop() ;
  12. extern void skipover() ;
  13. extern short scanpage() ;
  14. extern void skippage() ;
  15. extern int InPageList() ;
  16. /*
  17.  *   These are the globals it accesses.
  18.  */
  19. #ifdef DEBUG
  20. extern integer debug_flag;
  21. #endif  /* DEBUG */
  22. extern fontdesctype *fonthead ;
  23. extern real conv ;
  24. extern real vconv ;
  25. extern real alpha ;
  26. extern integer firstpage, lastpage ;
  27. extern integer firstseq, lastseq ;
  28. extern integer maxsecsize ;
  29. extern Boolean notfirst, notlast ;
  30. extern Boolean evenpages, oddpages, pagelist ;
  31. extern integer fontmem ;
  32. extern integer pagecount ;
  33. extern integer pagenum ;
  34. extern integer maxpages ;
  35. extern sectiontype *sections ;
  36. extern FILE *dvifile ;
  37. extern integer num, den, mag ;
  38. extern int overridemag ;
  39. extern integer swmem ;
  40. extern int quiet ;
  41. extern int actualdpi ;
  42. extern int vactualdpi ;
  43. extern Boolean reverse ;
  44. extern int totalpages ;
  45. extern integer fsizetol ;
  46. extern char *oname ;
  47. extern Boolean pprescan ;
  48. extern Boolean abspage ;
  49. extern char preamblecomment[] ;
  50. /*
  51.  *   This routine handles the processing of the preamble in the dvi file.
  52.  */
  53. void
  54. readpreamble()
  55. {
  56.    register int i ;
  57.    char *p ;
  58.  
  59.    if (dvibyte()!=247) error("! Bad DVI file: first byte not preamble") ;
  60.    if (dvibyte()!=2) error("! Bad DVI file: id byte not 2") ;
  61.    num = signedquad() ;
  62.    den = signedquad() ;
  63.    if (overridemag > 0) (void)signedquad() ;
  64.    else if (overridemag < 0) mag = (mag * signedquad() + 500) / 1000 ;
  65.    else mag = signedquad() ;
  66.    conv = (real) num * DPI * (real) mag / ( den * 254000000.0 ) ; 
  67.    vconv = (real) num * VDPI * (real) mag / ( den * 254000000.0 ) ; 
  68.    alpha = (((real)den / 7227.0) / 0x100000) * (25400000.0 / (real) num) ;
  69.    fsizetol = 1 + (integer)(DPI/(72270.0 * conv)) ;
  70.    if (!pprescan) {
  71.      for (i=dvibyte(),p=preamblecomment;i>0;i--,p++) *p=dvibyte() ;
  72.      *p='\0' ;
  73.      if (!quiet) {
  74.         (void)fprintf(stderr, "'") ;
  75. #ifdef VMCMS /* IBM: VM/CMS */
  76.         for(p=preamblecomment;*p;p++) (void)putc(ascii2ebcdic[*p], stderr) ;
  77. #else
  78. #ifdef MVSXA /* IBM: MVS/XA */
  79.         for(p=preamblecomment;*p;p++) (void)putc(ascii2ebcdic[*p], stderr) ;
  80. #else
  81.         for(p=preamblecomment;*p;p++) (void)putc(*p, stderr) ;
  82. #endif  /* IBM: VM/CMS */
  83. #endif
  84.         (void)fprintf(stderr, "' -> %s\n", oname) ;
  85.       }
  86.    } else
  87.       skipover(dvibyte()) ;
  88. }
  89.  
  90. /*
  91.  *   Finally, here's our main prescan routine.
  92.  */
  93. static integer firstmatch = -1, lastmatch = -1 ;
  94. void
  95. prescanpages()
  96. {
  97.    register int cmd ;
  98.    short ret = 0 ;
  99.    register integer thispageloc, thissecloc ;
  100.    register fontdesctype *f ;
  101.    register shalfword c ;
  102.    register long thissectionmem = 0 ;
  103.    integer mpagenum ;
  104.    integer pageseq = 0 ;
  105.    int ntfirst = notfirst ;
  106.  
  107.    readpreamble() ;
  108. /*
  109.  *   Now we look for the first page to process.  If we get to the end of
  110.  *   the file before the page, we complain (fatally).
  111.  *   Incidentally, we don't use the DVI file's bop backpointer to skip
  112.  *   over pages at high speed, because we want to look to for special
  113.  *   header that might be in skipped pages.
  114.  */
  115.    while (1) {
  116.       cmd = skipnop() ;
  117.       if (cmd==248)
  118.          error("! End of document before first specified page") ;
  119.       if (cmd!=139)
  120.          error("! Bad DVI file: expected bop") ;
  121.       thispageloc = ftell(dvifile) ; /* the location FOLLOWING the bop */
  122. #ifdef DEBUG
  123.       if (dd(D_PAGE))
  124. #ifdef SHORTINT
  125.       (void)fprintf(stderr,"bop at %ld\n", thispageloc) ;
  126. #else   /* ~SHORTINT */
  127.       (void)fprintf(stderr,"bop at %d\n", (int)thispageloc) ;
  128. #endif  /* ~SHORTINT */
  129. #endif  /* DEBUG */
  130.       pagenum = signedquad() ;
  131.       pageseq++ ;
  132.       mpagenum = abspage ? pageseq : pagenum ;
  133.       if (mpagenum == firstpage && ntfirst)
  134.          firstmatch++ ;
  135.       if (mpagenum == lastpage && notlast)
  136.          lastmatch++ ;
  137.       if (ntfirst && mpagenum == firstpage && firstmatch == firstseq)
  138.          ntfirst = 0 ;
  139.       if (ntfirst ||
  140.       ((evenpages && (pagenum & 1)) || (oddpages && (pagenum & 1)==0) ||
  141.        (pagelist && !InPageList(pagenum)))) {
  142.          skipover(40) ;
  143.          skippage() ;
  144.       } else {
  145.          if (notlast && mpagenum == lastpage)
  146.             lastmatch-- ;
  147.          break ;
  148.       }
  149.    }
  150. /*
  151.  *   Here we scan for each of the sections.  First we initialize some of
  152.  *   the variables we need.
  153.  */
  154.    while (maxpages > 0 && cmd != 248) {
  155.       for (f=fonthead; f; f=f->next) {
  156.          f->psname = 0 ;
  157.          if (f->loaded==1)
  158.             for (c=255; c>=0; c--)
  159.                f->chardesc[c].flags &= (STATUSFLAGS) ;
  160.       }
  161.       fontmem = swmem - OVERCOST ;
  162.       if (fontmem <= 1000)
  163.          error("! Too little VM in printer") ;
  164.  
  165. /*   The section begins at the bop command just before thispageloc (which may
  166.  *   be a page that was aborted because the previous section overflowed memory).
  167.  */
  168.       pagecount = 0 ;
  169.       (void)fseek(dvifile, (long)thispageloc, 0) ;
  170.       pagenum = signedquad() ;
  171.       skipover(40) ;
  172.       thissecloc = thispageloc ;
  173. /*
  174.  *   Now we have the loop that actually scans the pages.  The scanpage routine
  175.  *   returns 1 if the page scans okay; it returns 2 if the memory ran out
  176.  *   before any pages were completed (in which case we'll try to carry on
  177.  *   and hope for the best); it returns 0 if a page was aborted for lack
  178.  *   of memory. After each page, we mark the characters seen on that page
  179.  *   as seen for this section so that they will be downloaded.
  180.  */
  181.       ret = 0 ;
  182.       while (maxpages>0) {
  183.      if (!(evenpages && (pagenum & 1)) &&
  184.              !(oddpages && (pagenum & 1)==0) &&
  185.              !(pagelist && !InPageList(pagenum))) {
  186.             ret = scanpage() ;
  187.             if (ret == 0)
  188.                break ;
  189.             pagecount++ ;
  190.             maxpages-- ;
  191.      } else
  192.             skippage() ;
  193.          thissectionmem = swmem - fontmem - OVERCOST ;
  194.          mpagenum = abspage ? pageseq : pagenum ;
  195.          pageseq++ ;
  196.          if (mpagenum == lastpage && notlast)
  197.             lastmatch++ ;
  198.          if (notlast && mpagenum == lastpage && lastmatch == lastseq)
  199.             maxpages = -1 ; /* we are done after this page. */
  200.          if (reverse)
  201.             thissecloc = thispageloc ;
  202.          for (f=fonthead; f; f=f->next)
  203.             if (f->loaded==1) {
  204.                if (f->psflag & THISPAGE)
  205.                   f->psflag = PREVPAGE ;
  206.                for (c=255; c>=0; c--)
  207.                   if (f->chardesc[c].flags & THISPAGE)
  208.                      f->chardesc[c].flags = PREVPAGE |
  209.                (f->chardesc[c].flags & (STATUSFLAGS)) ;
  210.             }
  211.          cmd=skipnop() ;
  212.          if (cmd==248) break ;
  213.          if (cmd!=139)
  214.             error("! Bad DVI file: expected bop") ;
  215.          thispageloc = ftell(dvifile) ;
  216. #ifdef DEBUG
  217.          if (dd(D_PAGE))
  218. #ifdef SHORTINT
  219.          (void)fprintf(stderr,"bop at %ld\n", thispageloc) ;
  220. #else   /* ~SHORTINT */
  221.          (void)fprintf(stderr,"bop at %d\n", (int)thispageloc) ;
  222. #endif  /* ~SHORTINT */
  223. #endif  /* DEBUG */
  224.          pagenum = signedquad() ;
  225.          skipover(40) ;
  226.          if (ret==2 || (maxsecsize && pagecount >= maxsecsize))
  227.             break ;
  228.       }
  229. /*
  230.  *   Now we have reached the end of a section for some reason.
  231.  *   If there are any pages, we save the pagecount, section location,
  232.  *   and continue.
  233.  */
  234.       if (pagecount>0) {
  235.          register int fc = 0 ;
  236.          register sectiontype *sp ;
  237.          register charusetype *cp ;
  238.  
  239.          totalpages += pagecount ;
  240.          for (f=fonthead; f; f=f->next)
  241.             if (f->loaded==1 && f->psname)
  242.                fc++ ;
  243.          sp = (sectiontype *)mymalloc((integer)(sizeof(sectiontype) + 
  244.             fc * sizeof(charusetype) + sizeof(fontdesctype *))) ;
  245.          sp->bos = thissecloc ;
  246.          if (reverse) {
  247.             sp->next = sections ;
  248.             sections = sp ;
  249.          } else {
  250.             register sectiontype *p ;
  251.  
  252.             sp->next = NULL ;
  253.             if (sections == NULL)
  254.                sections = sp ;
  255.             else {
  256.                for (p=sections; p->next != NULL; p = p->next) ;
  257.                p->next = sp ;
  258.             }
  259.          }
  260.          sp->numpages = pagecount ;
  261. #ifdef DEBUG
  262.         if (dd(D_PAGE))
  263. #ifdef SHORTINT
  264.          (void)fprintf(stderr,"Have a section: %ld pages at %ld fontmem %ld\n", 
  265. #else   /* ~SHORTINT */
  266.          (void)fprintf(stderr,"Have a section: %d pages at %d fontmem %d\n", 
  267. #endif  /* ~SHORTINT */
  268.          (integer)pagecount, (integer)thissecloc, (integer)thissectionmem) ;
  269. #endif  /* DEBUG */
  270.          cp = (charusetype *) (sp + 1) ;
  271.          fc = 0 ;
  272.          for (f=fonthead; f; f=f->next)
  273.             if (f->loaded==1 && f->psname) {
  274.                register halfword b, bit ;
  275.  
  276.                cp->psfused = (f->psflag & PREVPAGE) ;
  277.                f->psflag = 0 ;
  278.                cp->fd = f ;
  279.                c = 0 ;
  280.                for (b=0; b<16; b++) {
  281.                   cp->bitmap[b] = 0 ;
  282.                   for (bit=32768; bit!=0; bit>>=1) {
  283.                      if (f->chardesc[c].flags & PREVPAGE)
  284.                         cp->bitmap[b] |= bit ;
  285.                   c++ ;
  286.                   }
  287.                }
  288.                cp++ ;
  289.             }
  290.          cp->fd = NULL ;
  291.       }
  292.    }
  293. }
  294.